package cn.siriusbot.siriuspro.web.hook;

import cn.siriusbot.siriuspro.bot.BotApiBuilder;
import cn.siriusbot.siriuspro.bot.application.SiriusApplicationInfo;
import cn.siriusbot.siriuspro.bot.plugin.HookPlugInClient;
import cn.siriusbot.siriuspro.bot.plugin.PlugInClient;
import cn.siriusbot.siriuspro.bot.plugin.PlugInFactory;
import cn.siriusbot.siriuspro.error.MsgException;
import cn.siriusbot.siriuspro.web.R.R;
import com.alibaba.fastjson2.JSONObject;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.async.DeferredResult;

/**
 * 长轮询HTTP钩子
 */
@Log4j2
@RestController
@RequestMapping("/hook")
public class AsyncHook {

    @Autowired
    private PlugInFactory plugInFactory;

    @Autowired
    private BotApiBuilder botApiBuilder;


    /**
     * 注册钩子
     */
    @PostMapping("/register")
    public R registerHook(
            @RequestBody String body
    ) {
        // 注册钩子验证插件信息
        SiriusApplicationInfo info = JSONObject.parseObject(body, SiriusApplicationInfo.class);
        // 检验插件信息
        if (ObjectUtils.isEmpty(info.getPackageName())) {
            throw new MsgException(500, "插件包名不能为空!");
        }
        if (ObjectUtils.isEmpty(info.getAppName())) {
            throw new MsgException(500, "插件名不能为空!");
        }
        if (ObjectUtils.isEmpty(info.getAppAuthor())) {
            throw new MsgException(500, "插件作者不能为空!");
        }
        if (ObjectUtils.isEmpty(info.getAppPath())) {
            throw new MsgException(500, "插件路径不能为空!");
        }
        if (ObjectUtils.isEmpty(info.getAppVersion())) {
            throw new MsgException(500, "插件版本不能为空!");
        }
        if (ObjectUtils.isEmpty(info.getAppDesc())) {
            info.setAppDesc("");
        }
        HookPlugInClient hookPlugInClient = new HookPlugInClient(info, botApiBuilder.build(info));
        this.plugInFactory.add(hookPlugInClient);
        R r = new R()
                .setCode(0)
                .setMsg("插件验证通过")
                .setData(hookPlugInClient.getUuid());
        log.info(String.format("[async-hook] 注册钩子应用验证通过 -> %s", info));
        return r;
    }

    @GetMapping("/get/{session}")
    public DeferredResult<String> getMessage(
            @PathVariable String session
    ) {
        PlugInClient hookPlugInClient = plugInFactory.getPlugInClientBySessionId(session);
        if (hookPlugInClient instanceof HookPlugInClient client) {
            DeferredResult<String> result = new DeferredResult<>(10000L);    // 30秒过期
            result.onTimeout(() -> result.setResult(new R()
                    .setCode(302)
                    .setMsg("暂无消息")
                    .toString()
            ));
            client.setHook(result);
            return result;
        }
        throw new MsgException(300, "构建请求错误，session会话过期或不存在!");
    }

}
